import { any } from "../core/logic"
import { guid } from "../core/utils";

class Texture {
    constructor(opts) {
        let { image, dimension, viewDimension, format, usage, sampler, multisampled, sampleType, uvIndex, uvTransform, texture } = opts;
        this.format = any(format, 'rgba8unorm');
        this.dimension = any(dimension, '2d');
        this.viewDimension = any(viewDimension, '2d');
        this.usage = any(usage, GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT);
        this.sampler = any(sampler, {
            addressModeU: "repeat",
            addressModeV: "repeat",
            addressModeW: "repeat",
            magFilter: "linear",
            minFilter: "linear",
            mipmapFilter: "linear"
        });
        this.multisampled = any(multisampled, false);
        this.sampleType = any(sampleType, 'float');
        this.uvIndex = uvIndex;
        this.uvTransform = uvTransform;
        this.image = image;
        this.texture = texture;
        this.id = any(opts.id, guid())
        this.mipMap = any(opts.mipMap, true)
        this.bigTextureQuality = any(opts.bigTextureQuality, 1.0)
    }
    get format() {
        return this._format
    }
    set format(v) {
        this._format = v;
        return this;
    }
    get dimension() {
        return this._dimension
    }
    set dimension(v) {
        this._dimension = v;
        return this;
    }
    get viewDimension() {
        return this._viewDimension
    }
    set viewDimension(v) {
        this._viewDimension = v;
        return this;
    }
    get usage() {
        return this._usage
    }
    set usage(v) {
        this._usage = v;
        return this;
    }
    get sampler() {
        return this._sampler
    }
    set sampler(v) {
        this._sampler = v;
        return this;
    }
    get multisampled() {
        return this._multisampled
    }
    set multisampled(v) {
        this._multisampled = v;
        return this;
    }
    get sampleType() {
        return this._sampleType
    }
    set sampleType(v) {
        this._sampleType = v;
        return this;
    }
    get uvIndex() {
        return this._uvIndex
    }
    set uvIndex(v) {
        this._uvIndex = v;
        return this;
    }
    get uvTransform() {
        return this._uvTransform
    }
    set uvTransform(v) {
        this._uvTransform = v;
        return this;
    }
    get image() {
        return this._image
    }
    set image(v) {
        this._image = v;
        return this;
    }
    get texture() {
        return this._texture
    }
    set texture(v) {
        this._texture = v;
        return this;
    }
    toGPU() {
        let { image, texture, dimension, viewDimension, format, usage, sampler, multisampled, sampleType, uvIndex, uvTransform } = this;
        return {
            image,
            dimension,
            viewDimension,
            format,
            usage,
            sampler,
            multisampled,
            sampleType,
            uvIndex,
            uvTransform,
            texture
        }
    }
}
export { Texture }
export function parsePngDimensions(uint8Array) {
    if (uint8Array.length < 24) {
        throw new Error('数据太短，无法解析 PNG 图片');
    }
    // 检查 PNG 文件头
    if (uint8Array[0] !== 0x89 || uint8Array[1] !== 0x50 || uint8Array[2] !== 0x4E || uint8Array[3] !== 0x47 ||
        uint8Array[4] !== 0x0D || uint8Array[5] !== 0x0A || uint8Array[6] !== 0x1A || uint8Array[7] !== 0x0A) {
        throw new Error('不是有效的 PNG 文件');
    }
    // 宽度和高度在第 16 到 23 字节
    const width = (uint8Array[16] << 24) | (uint8Array[17] << 16) | (uint8Array[18] << 8) | uint8Array[19];
    const height = (uint8Array[20] << 24) | (uint8Array[21] << 16) | (uint8Array[22] << 8) | uint8Array[23];
    return { width, height };
}
export function parseJpegDimensions(uint8Array) {
    let index = 2; // 跳过文件头 FF D8
    while (index < uint8Array.length - 4) {
        if (uint8Array[index] !== 0xFF) {
            throw new Error('无效的 JPEG 文件');
        }
        const marker = uint8Array[index + 1];
        const segmentLength = (uint8Array[index + 2] << 8) | uint8Array[index + 3];
        if (marker === 0xC0 || marker === 0xC1 || marker === 0xC2 || marker === 0xC3 || marker === 0xC5 || marker === 0xC6 || marker === 0xC7 || marker === 0xC9 || marker === 0xCA || marker === 0xCB || marker === 0xCD || marker === 0xCE || marker === 0xCF) {
            // 找到 SOF 标记
            const height = (uint8Array[index + 5] << 8) | uint8Array[index + 6];
            const width = (uint8Array[index + 7] << 8) | uint8Array[index + 8];
            return { width, height };
        }
        index += segmentLength + 2;
    }
    throw new Error('未找到有效的 JPEG 尺寸信息');
}
export function detectImageType(uint8Array) {
    if (uint8Array.length < 4) {
        return null; // 数据太短，无法确定类型
    }
    // 检查 PNG 文件头
    if (uint8Array[0] === 0x89 && uint8Array[1] === 0x50 && uint8Array[2] === 0x4E && uint8Array[3] === 0x47 &&
        uint8Array[4] === 0x0D && uint8Array[5] === 0x0A && uint8Array[6] === 0x1A && uint8Array[7] === 0x0A) {
        return 'image/png';
    }
    // 检查 JPEG 文件头
    if (uint8Array[0] === 0xFF && uint8Array[1] === 0xD8 && uint8Array[2] === 0xFF) {
        // 检查接下来的两个字节，以进一步确认是 JPEG
        if (uint8Array[3] === 0xE0 || uint8Array[3] === 0xE1) {
            return 'image/jpeg';
        }
    }
    return null; // 无法识别的图片类型
}

export function getImageDimensions(uint8Array) {
    const type = detectImageType(uint8Array);
    if (!type) {
        throw new Error('无法识别的图片类型');
    }
    var dimensions
    if (type === 'image/png') {
        dimensions = parsePngDimensions(uint8Array);
        dimensions.imageType = 'image/png'
        return dimensions
    } else if (type === 'image/jpeg') {
        dimensions = parseJpegDimensions(uint8Array);
        dimensions.imageType = 'image/jpeg'
        return dimensions
    } else {
        throw new Error('不支持的图片类型');
    }
}